﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SignalRExtensions
{
    [Authorize]
    public class MessageHub : Hub
    {
        IAuthUser _authUser;
        ICache _cache;
        ILogger<MessageHub> _logger;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="authUser"></param>
        /// <param name="cache"></param>
        public MessageHub(IAuthUser authUser, ICache cache, ILogger<MessageHub> logger)
        {

            _authUser = authUser;
            _cache = cache;
            _logger = logger;
        }



        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override Task OnConnectedAsync()
        {
            _logger.LogDebug($"上线==》--{_authUser.Id},{_authUser.UserName}.{_authUser.DisplayName}");
            _cache.SetAsync($"chat_{_authUser.Id}", Context.ConnectionId);
            var chats = _cache.GetKeys($"chat_*").Result;
            _logger.LogDebug($"租户在线用户:{JSON.Serialize(chats)}");
            Clients.Client(this.Context.ConnectionId).SendAsync("getId", Context.ConnectionId);
            Clients.Client(this.Context.ConnectionId).SendAsync("welcome", "欢迎您！");
            Clients.Groups("sys").SendAsync("onLine", _authUser.Id, Context.ConnectionId);
            return base.OnConnectedAsync();
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="exception"></param>
        /// <returns></returns>
        public override Task OnDisconnectedAsync(Exception? exception)
        {
            _logger.LogDebug($"离线：==》{_authUser.Id},{_authUser.UserName},{_authUser.DisplayName}");
            _cache.RemoveAsync($"chat_{_authUser.Id}");

            Clients.Groups("sys").SendAsync("offLine", _authUser.Id, Context.ConnectionId);
            return base.OnDisconnectedAsync(exception);
        }
        public async Task Ping()
        {
            await Clients.Caller.SendAsync("ping");
        }
        /// <summary>
        /// 
        /// </summary>
        public static Action<IHubCallerClients, HubCallerContext, string>? OnMessage { get; set; }

        /// <summary>
        /// 处理文本流
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public   Task SendMessage(string msg)
        {
            if (OnMessage != null) OnMessage(Clients, this.Context, msg);
            return Task.CompletedTask;
        }


        /// <summary>
        /// 向某个用户发消息
        /// </summary>
        /// <param name="method"></param>
        /// <param name="userId"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendMessageToUser(string userId, string method, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9)
        {
            var connectionId = _cache.Get<string>($"chat_{userId}");
            if (string.IsNullOrEmpty(connectionId))
            {
                _logger.LogDebug($"用户 {userId} 不在线");
                return;
            }
            await Clients.Client(connectionId).SendAsync(method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
            // _logger.LogDebug($"消息已经发送 userId：{userId}  method：{method} message：{arg1}");
        }


        /// <summary>
        /// 向某个组发送消息
        /// </summary>
        /// <param name="groupName">组名</param>
        /// <param name="method">客户端方法名</param>
        /// <param name="message">消息内容</param>
        /// <returns></returns>
        public async Task SendMessageToGroup(string groupName, string method, object? arg1, object? arg2, object? arg3, object? arg4, object? arg5, object? arg6, object? arg7, object? arg8, object? arg9)
        {
            await Clients.Group(groupName).SendAsync(method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
        }

        /// <summary>
        /// 将当前用户加入某个组
        /// </summary>
        /// <param name="groupName">组名</param>
        /// <returns></returns>
        public async Task AddToGroup(string groupName)
        {
            await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
            _logger.LogDebug($"用户 {_authUser.UserName} 已加入组 {groupName}");
        }

        /// <summary>
        /// 将当前用户从某个组移除
        /// </summary>
        /// <param name="groupName">组名</param>
        /// <returns></returns>
        public async Task RemoveFromGroup(string groupName)
        {
            await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
            _logger.LogDebug($"用户 {_authUser.UserName} 已从组 {groupName} 移除");
        }
    }
}
